package cn.itcast.web.controller.system;

import cn.itcast.domain.system.Module;
import cn.itcast.domain.system.Role;
import cn.itcast.service.system.ModuleService;
import cn.itcast.service.system.RoleService;
import cn.itcast.web.controller.BaseController;
import com.alibaba.druid.support.json.JSONUtils;
import com.github.pagehelper.PageInfo;
import com.rabbitmq.tools.json.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/system/role")
public class RoleController extends BaseController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private ModuleService moduleService;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    /*
    url：/system/role/list.do
    作用：查询角色列表
    参数： 无
    返回值： 角色列表页面(system/role/role-list.jsp)
  */
    @RequestMapping("/list")
    public String list(@RequestParam(defaultValue = "1") Integer pageNum,@RequestParam(defaultValue = "5") Integer pageSize){
        //企业id应该是登陆者所属的企业id,问题： 我们还没有实现登陆功能,所以我们今天先写死companyId
        String companyId = "1";

        //1. 查询角色列表
        PageInfo<Role> pageInfo = roleService.findByPage(pageNum,pageSize,companyId);

        //2. 存储request域中
        request.setAttribute("pageInfo",pageInfo);
        //3. 回到页面
        return "system/role/role-list";
    }


    /*
      url：/system/role/toAdd.do
      作用：进入角色添加页面
      参数：无
      返回值： system/role/role-add.jsp
   */
    @RequestMapping("/toAdd")
    public String toAdd(){
        //1. 查询所有角色,用于展示父角色
        String companyId = getLoginUserCompanyId();
        List<Role> roleList = roleService.findAll(companyId);

        //2. 存储到请求域中
        request.setAttribute("roleList",roleList);

        //3. 返回到添加角色的页面
        return "system/role/role-add";
    }


    /*
     url：/system/role/edit.do
     作用：保存添加与保存修改
     参数：角色对象
     返回值： 角色列表
  */
    @RequestMapping("/edit")
    public String edit(Role role){
        //补充数据，因为这些数据是来自于登陆者
        String companyId = getLoginUserCompanyId();
        String companyName= getLoginUserCompanyName();
        role.setCompanyId(companyId);
        role.setCompanyName(companyName);

        //1.判断role是否携带id过来，如果没有携带则是添加
        if(StringUtils.isEmpty(role.getId())){
            roleService.save(role);
        }else {
            //2. 如果携带id过来则是修改
            roleService.update(role);
        }
        return "redirect:/system/role/list.do";
    }


    /*
        url：/system/role/toUpdate.do?id=100101
        作用：进入角色修改页面
        参数：角色id
        返回值：system/role/role-update.jsp
     */
    @RequestMapping("/toUpdate")
    public String toUpdate(String id){
        //1. 根据id查询角色
        Role role = roleService.findById(id);

        //2. 把角色存储到请求域中
        request.setAttribute("role",role);

        //3.查询全部角色，用于父角色的信息回显
        String companyId = getLoginUserCompanyId();
        List<Role> roleList = roleService.findAll(companyId);
        request.setAttribute("roleList",roleList);


        //4. 返回更新页面
        return "system/role/role-update";

    }

    /*
     url：system/role/delete.do
     作用：删除角色
     参数：角色id
     返回值：json
  */
    @RequestMapping("/delete")
    public String  delete(String id){
        roleService.delete(id);
        return "redirect:/system/role/list.do";
    }



    /*
    url：/system/role/roleModule.do?roleid=4028a1c34ec2e5c8014ec2ebf8430001
    作用：进入角色分配权限页面
    参数：角色id
    返回值：system/role/role-module.jsp
     */
    @RequestMapping("/roleModule")
    public String  roleModule(String roleid) {
        //1. 根据角色id查询角色
        Role role = roleService.findById(roleid);
        //2. 存储到请求域
        request.setAttribute("role",role);
        return "system/role/role-module";
    }


    /*

    var zNodes =[
        { id:1, pId:0, name:"saas管理", open:true},
        { id:11, pId:1, name:"企业管理"},
        { id:111, pId:1, name:"模块管理"}
    ]

   url：/system/role/getTreeNodes.do
   作用：得到ztree所要的数据
   参数：roleid : 角色id
   返回值：json对象
    */
    @RequestMapping("/getTreeNodes")
    @ResponseBody
    public List<Map<String,Object>>  getTreeNodes(String roleid) {
        //查询redis中的模块树
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        List<Module> moduleList = (List<Module>) ops.get("module_tree_nodes");

        //判断模块树是否存在
        if (moduleList==null){
            //若不存在，查询数据库
            moduleList = moduleService.findAll();

            //将结果放入redis中
            ops.set("module_tree_nodes",moduleList,2L, TimeUnit.DAYS);
        }
        //1. 查询所有模块

        //2. 定义一个集合接收结果
        List<Map<String,Object>> resultList = new ArrayList<>();

        //3.把当前角色的权限id全部查询出来。
        List<String> moduleIdList =  moduleService.findRoleModuleByRoleId(roleid);

        //4. 遍历所有的模块，把模块的信息存储到结果中
        for (Module module : moduleList) {
            //一个module就要转换为一个map
            Map<String,Object> map = new HashMap<>();
            map.put("id",module.getId());
            map.put("pId",module.getParentId());
            map.put("name",module.getName());
            map.put("open",true);
            //如果当前角色拥有模块才选中。
            if(moduleIdList.contains(module.getId())) {
                map.put("checked", true);//选中
            }
            //把map存储结果的List中
            resultList.add(map);
        }


        //5. 返回
        return resultList;

    }

    /*
      url：/system/role/updateRoleModule
      作用：更新角色的权限
      参数：roleid 角色id   moduleIds 模块的ids  moduleIds=1,2,3
            moduleIds参数接收的方式：
                    方式一： 直接使用字符串接收   1,2,3
                    方式二： 可以使用数组接收， springmvc自动帮你切割
      返回值：角色列表页面
   */

   @RequestMapping("/updateRoleModule")
    public String  updateRoleModule(String roleid,String[] moduleIds) {
          roleService.updateRoleModule(roleid,moduleIds);
          return "redirect:/system/role/list.do";
    }
}
